/*
 * Copyright 2013-2014 VTT Biotechnology
 * This file is part of AntND.
 *
 * AntND is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * AntND is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * AntND; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
 * Fifth Floor, Boston, MA 02110-1301 USA
 */
package ND.modules.reactionOP.addReaction;

import ND.main.NDCore;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import org.sbml.jsbml.KineticLaw;
import org.sbml.jsbml.LocalParameter;
import org.sbml.jsbml.Model;
import org.sbml.jsbml.Reaction;
import org.sbml.jsbml.Species;
import org.sbml.jsbml.SpeciesReference;

/**
 *
 * @author scsandra
 */
public class ReactionForm extends javax.swing.JInternalFrame implements ActionListener {

        private JTextArea area;
        private StringBuffer text;
        private boolean isReactant = true;
        private AddingForm addPanel;
        private Reaction reaction;
        private Model m;
        private List<Species> species;

        /**
         * Creates new form ReactionForm
         */
        public ReactionForm(Model m, String reactionName) {
                this.m = m;
                initComponents();

                this.text = new StringBuffer();
                this.text.append(reactionName).append("\n");
                addPanel = new AddingForm(this);
                JPanel textPanel = new JPanel();
                textPanel.setSize(new Dimension(700, 500));
                this.createTextPanel(textPanel);
                this.Cards.add(addPanel, "Adding compound");
                this.Cards.add(textPanel, "Showing reaction");

                CardLayout cl = (CardLayout) this.Cards.getLayout();
                cl.show(Cards, "Showing reaction");

                this.reaction = new Reaction();
                this.reaction.setId(reactionName);
                this.species = new ArrayList<>();
                
                setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        }

        /**
         * This method is called from within the constructor to initialize the
         * form. WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
        private void initComponents() {

                ActionPanel = new javax.swing.JPanel();
                AddReactant = new javax.swing.JButton();
                AddProduct = new javax.swing.JButton();
                ubound = new javax.swing.JTextField();
                jLabel1 = new javax.swing.JLabel();
                jLabel2 = new javax.swing.JLabel();
                lbound = new javax.swing.JTextField();
                Reset = new javax.swing.JButton();
                Add = new javax.swing.JButton();
                Cancel = new javax.swing.JButton();
                Cards = new javax.swing.JPanel();

                setBackground(new java.awt.Color(255, 255, 255));

                ActionPanel.setBackground(new java.awt.Color(255, 255, 255));
                ActionPanel.setMaximumSize(new java.awt.Dimension(500, 92));

                AddReactant.setText("Add Reactant");
                AddReactant.addActionListener(new java.awt.event.ActionListener() {
                        public void actionPerformed(java.awt.event.ActionEvent evt) {
                                AddReactantActionPerformed(evt);
                        }
                });

                AddProduct.setText("Add Product");
                AddProduct.addActionListener(new java.awt.event.ActionListener() {
                        public void actionPerformed(java.awt.event.ActionEvent evt) {
                                AddProductActionPerformed(evt);
                        }
                });

                ubound.setText("1000");

                jLabel1.setText("Bounds:");

                jLabel2.setText("-");

                lbound.setText("-1000");

                Reset.setText("Reset");
                Reset.addActionListener(new java.awt.event.ActionListener() {
                        public void actionPerformed(java.awt.event.ActionEvent evt) {
                                ResetActionPerformed(evt);
                        }
                });

                Add.setText("Add");
                Add.addActionListener(new java.awt.event.ActionListener() {
                        public void actionPerformed(java.awt.event.ActionEvent evt) {
                                AddActionPerformed(evt);
                        }
                });

                Cancel.setText("Cancel");
                Cancel.addActionListener(new java.awt.event.ActionListener() {
                        public void actionPerformed(java.awt.event.ActionEvent evt) {
                                CancelActionPerformed(evt);
                        }
                });

                javax.swing.GroupLayout ActionPanelLayout = new javax.swing.GroupLayout(ActionPanel);
                ActionPanel.setLayout(ActionPanelLayout);
                ActionPanelLayout.setHorizontalGroup(
                        ActionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(ActionPanelLayout.createSequentialGroup()
                                .addGap(25, 25, 25)
                                .addGroup(ActionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(AddReactant, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(AddProduct, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                .addGroup(ActionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(ActionPanelLayout.createSequentialGroup()
                                                .addGap(26, 26, 26)
                                                .addComponent(jLabel1)
                                                .addGap(18, 18, 18)
                                                .addComponent(lbound, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(jLabel2)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(ubound, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 42, Short.MAX_VALUE)
                                                .addComponent(Reset, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addGap(26, 26, 26))
                                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ActionPanelLayout.createSequentialGroup()
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                .addComponent(Add)
                                                .addGap(5, 5, 5)
                                                .addComponent(Cancel)
                                                .addContainerGap())))
                );
                ActionPanelLayout.setVerticalGroup(
                        ActionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(ActionPanelLayout.createSequentialGroup()
                                .addGroup(ActionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(ActionPanelLayout.createSequentialGroup()
                                                .addGap(29, 29, 29)
                                                .addGroup(ActionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                        .addComponent(ubound, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                        .addComponent(jLabel1)
                                                        .addComponent(jLabel2)
                                                        .addComponent(lbound, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                                        .addGroup(ActionPanelLayout.createSequentialGroup()
                                                .addContainerGap()
                                                .addGroup(ActionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addGroup(ActionPanelLayout.createSequentialGroup()
                                                                .addComponent(Reset)
                                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                                .addGroup(ActionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                                        .addComponent(Add)
                                                                        .addComponent(Cancel)))
                                                        .addGroup(ActionPanelLayout.createSequentialGroup()
                                                                .addComponent(AddReactant)
                                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                                .addComponent(AddProduct)
                                                                .addGap(0, 0, Short.MAX_VALUE)))))
                                .addContainerGap())
                );

                getContentPane().add(ActionPanel, java.awt.BorderLayout.NORTH);

                Cards.setBackground(new java.awt.Color(255, 255, 255));
                Cards.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(33, 212, 134), 4, true));
                Cards.setMinimumSize(new java.awt.Dimension(500, 500));
                Cards.setLayout(new java.awt.CardLayout());
                getContentPane().add(Cards, java.awt.BorderLayout.CENTER);
        }// </editor-fold>//GEN-END:initComponents

        private void AddReactantActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AddReactantActionPerformed
                this.addPanel.reset();
                CardLayout cl = (CardLayout) this.Cards.getLayout();
                cl.show(Cards, "Adding compound");
                this.isReactant = true;
        }//GEN-LAST:event_AddReactantActionPerformed

        private void AddProductActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AddProductActionPerformed
                this.addPanel.reset();
                CardLayout cl = (CardLayout) this.Cards.getLayout();
                cl.show(Cards, "Adding compound");
                this.isReactant = false;
        }//GEN-LAST:event_AddProductActionPerformed

        private void AddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AddActionPerformed
                for (Species sp : this.species) {
                        if (!m.containsSpecies(sp.getId())) {
                                m.addSpecies(sp);
                        }
                }

                KineticLaw law = new KineticLaw();
                LocalParameter lboundP = new LocalParameter("LOWER_BOUND");
                lboundP.setValue(Double.valueOf(this.lbound.getText()));
                law.addLocalParameter(lboundP);
                LocalParameter uboundP = new LocalParameter("UPPER_BOUND");
                uboundP.setValue(Double.valueOf(this.ubound.getText()));
                law.addLocalParameter(uboundP);
                reaction.setKineticLaw(law);
                m.addReaction(reaction);
                
                this.setVisible(false);

        }//GEN-LAST:event_AddActionPerformed

        private void ResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ResetActionPerformed
                this.text.delete(0, this.text.length());
                this.area.setText("");
        }//GEN-LAST:event_ResetActionPerformed

        private void CancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancelActionPerformed
                this.setVisible(false);
        }//GEN-LAST:event_CancelActionPerformed
        // Variables declaration - do not modify//GEN-BEGIN:variables
        private javax.swing.JPanel ActionPanel;
        private javax.swing.JButton Add;
        private javax.swing.JButton AddProduct;
        private javax.swing.JButton AddReactant;
        private javax.swing.JButton Cancel;
        private javax.swing.JPanel Cards;
        private javax.swing.JButton Reset;
        private javax.swing.JLabel jLabel1;
        private javax.swing.JLabel jLabel2;
        private javax.swing.JTextField lbound;
        private javax.swing.JTextField ubound;
        // End of variables declaration//GEN-END:variables

        private void createTextPanel(JPanel textPanel) {
                this.area = new JTextArea();
                textPanel.add(this.area);
        }

        private void SetCompound() {
                if (this.isReactant) {
                        this.text.append("Reactant: ");
                } else {
                        this.text.append("Product: ");
                }
                this.text.append(addPanel.getSto()).append(" ").append(addPanel.getId()).append(" - ").append(addPanel.getCName()).append("\n");
                this.area.setText(this.text.toString());
                CardLayout cl = (CardLayout) this.Cards.getLayout();
                cl.show(Cards, "Showing reaction");

                SpeciesReference spref = new SpeciesReference();
                if (m.containsSpecies(addPanel.getId())) {
                        try {
                                spref.setStoichiometry(Double.valueOf(addPanel.getSto()));
                        } catch (Exception e) {
                                NDCore.getDesktop().displayErrorMessage("Stoichiometry should be a number");
                        }

                        //spref.setId(addPanel.getId());
                        spref.setSpecies(m.getSpecies(addPanel.getId()));

                } else {
                        try {
                                spref.setStoichiometry(Double.valueOf(addPanel.getSto()));
                        } catch (Exception e) {
                                NDCore.getDesktop().displayErrorMessage("Stoichiometry should be a number");
                        }
                        Species sp = new Species(addPanel.getId());
                        this.species.add(sp);
                       // spref.setId(addPanel.getId());
                        spref.setSpecies(sp);
                }

                if (this.isReactant) {
                        this.reaction.addReactant(spref);
                } else {
                        this.reaction.addProduct(spref);
                }
        }

        @Override
        public void actionPerformed(ActionEvent e) {
                SetCompound();
        }
}
